<template>
  <div class="map-container">
    <div id="map" class="map"></div>
    <div class="toolbar">
      <button @click="startMeasureLength" :class="{ active: measuringLength }">测距</button>
      <button @click="startMeasureArea" :class="{ active: measuringArea }">测面</button>
      <button @click="clearMeasure">清除</button>
    </div>
  </div>
</template>

<script>
import 'leaflet/dist/leaflet.css';
import L from 'leaflet';
// import 'leaflet-geometryutil';

export default {
  name: 'MeasureTool',
  
  data() {
    return {
      map: null,
      drawLayer: null,
      tempLayer: null,
      measureTooltip: null,
      measuringLength: false,
      measuringArea: false,
      points: [],
      tempLine: null
    };
  },

  mounted() {
    this.initMap();
  },

  methods: {
    initMap() {
      // 初始化地图
      this.map = L.map('map', {
        center: [43.792818, 87.617733],
        zoom: 13,
        // crs: L.CRS.EPSG3857  // 明确指定坐标系
      });

      // 添加天地图底图
      L.tileLayer('https://t{s}.tianditu.gov.cn/vec_w/wmts?' + 
        'SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles' +
        '&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=8c88eba266a165eac9c085724708f2f9', {
        maxZoom: 18,
        subdomains: ['0', '1', '2', '3', '4', '5', '6', '7']
      }).addTo(this.map);

      // 添加天地图标注
      L.tileLayer('https://t{s}.tianditu.gov.cn/cva_w/wmts?' +
        'SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles' +
        '&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=8c88eba266a165eac9c085724708f2f9', {
        maxZoom: 18,
        subdomains: ['0', '1', '2', '3', '4', '5', '6', '7']
      }).addTo(this.map);

      // 创建绘制图层
      this.drawLayer = L.featureGroup().addTo(this.map);
      this.tempLayer = L.featureGroup().addTo(this.map);

      // 只绑定点击事件，mousemove事件在开始测量时绑定
      this.map.on('click', this.onMapClick);
    },

    startMeasureLength() {
      this.clearMeasure();
      this.measuringLength = true;
      this.measuringArea = false;
      this.points = [];
      // 重新绑定鼠标移动事件
      this.map.on('mousemove', this.onMouseMove);
      this.map.getContainer().style.cursor = 'crosshair';
    },

    startMeasureArea() {
      this.clearMeasure();
      this.measuringArea = true;
      this.measuringLength = false;
      this.points = [];
      // 重新绑定鼠标移动事件
      this.map.on('mousemove', this.onMouseMove);
      this.map.getContainer().style.cursor = 'crosshair';
    },

    clearMeasure() {
      this.measuringLength = false;
      this.measuringArea = false;
      // 清除所有图层
      this.tempLayer.clearLayers();
      this.drawLayer.clearLayers();
      this.map.off('mousemove', this.onMouseMove);
      this.map.getContainer().style.cursor = '';
      if (this.measureTooltip) {
        this.map.removeLayer(this.measureTooltip);
      }
      this.points = [];
      this.tempLine = null;
      this.measureTooltip = null;
    },

    onMapClick(e) {
      if (!this.measuringLength && !this.measuringArea) return;

      // 处理双击事件
      if (e.originalEvent && e.originalEvent.detail === 2) {
        if (this.measuringArea && this.points.length >= 2) {
          // 先清除临时图层和提示
          this.tempLayer.clearLayers();
          if (this.measureTooltip) {
            this.map.removeLayer(this.measureTooltip);
          }

          // 添加闭合点
          this.points.push(this.points[0]);

          // 闭合多边形
          const polygon = L.polygon(this.points, {
            color: '#ff0000',
            weight: 2,
            fill: true,
            fillColor: '#ff0000',
            fillOpacity: 0.2
          }).addTo(this.drawLayer);

          // 计算并显示面积
          const area = this.calculateArea(this.points);
          this.measureTooltip = L.tooltip({
            permanent: true,
            direction: 'center',
            className: 'area-tooltip'
          })
            .setLatLng(polygon.getBounds().getCenter())
            .setContent(this.formatArea(area))
            .addTo(this.map);

          // 停止测量状态但保留结果
          this.measuringArea = false;
          this.tempLayer.clearLayers();
          // 先移除事件监听，再清空点集合
          this.map.off('mousemove');
          this.points = [];
          this.map.getContainer().style.cursor = '';
          return;
        }
        // 如果是测距双击，直接结束
        if (this.measuringLength) {
          this.measuringLength = false;
          this.map.off('mousemove', this.onMouseMove);
          this.map.getContainer().style.cursor = '';
        }
        return;
      }

      // 如果已经完成测量，不继续处理
      if (!this.measuringLength && !this.measuringArea) return;

      // 添加点
      this.points.push(e.latlng);

      // 绘制点
      if (this.points.length === 1) {
        L.circleMarker(e.latlng, {
          color: '#ff0000',
          radius: 4
        }).addTo(this.drawLayer);
      }

      // 绘制线段
      if (this.points.length > 1) {
        L.polyline([
          this.points[this.points.length - 2],
          this.points[this.points.length - 1]
        ], {
          color: '#ff0000',
          weight: 2
        }).addTo(this.drawLayer);

        // 更新测量提示
        if (this.measuringLength) {
          this.updateLengthTooltip();
        } else if (this.measuringArea && this.points.length > 2) {
          this.updateAreaTooltip();
        }
      }
    },

    onMouseMove(e) {
      // 如果没有在测量状态或没有点，直接返回
      if (this.points.length === 0) return;
      if (!this.measuringLength && !this.measuringArea) {
        this.tempLayer.clearLayers();
        return;
      }

      this.tempLayer.clearLayers();

      // 绘制临时线段
      const tempPoints = [...this.points, e.latlng];
      if (this.measuringArea && this.points.length > 2) {
        // 显示闭合多边形
        const closedPoints = [...tempPoints, tempPoints[0]]; // 确保多边形闭合
        L.polygon(closedPoints, {
          color: '#ff0000',
          weight: 2,
          fill: true,
          fillColor: '#ff0000',
          fillOpacity: 0.2,
          dashArray: '5,5'
        }).addTo(this.tempLayer);
      } else {
        // 显示临时线段
        L.polyline(tempPoints, {
          color: '#ff0000',
          weight: 2,
          dashArray: '5,5'
        }).addTo(this.tempLayer);
      }

      // 更新提示信息
      if (this.measuringLength) {
        this.updateLengthTooltip(e.latlng);
      } else if (this.measuringArea && this.points.length > 1) {
        this.updateAreaTooltip(e.latlng);
      }
    },

    updateLengthTooltip(tempPoint) {
      let totalLength = 0;
      for (let i = 1; i < this.points.length; i++) {
        totalLength += this.points[i-1].distanceTo(this.points[i]);
      }
      if (tempPoint) {
        totalLength += this.points[this.points.length-1].distanceTo(tempPoint);
      }

      if (this.measureTooltip) {
        this.map.removeLayer(this.measureTooltip);
      }

      const position = tempPoint || this.points[this.points.length-1];
      this.measureTooltip = L.tooltip({
        permanent: true,
        direction: 'top'
      })
        .setLatLng(position)
        .setContent(this.formatDistance(totalLength))
        .addTo(this.map);
    },

    updateAreaTooltip(tempPoint) {
      if (this.points.length < 2) return;

      let points = [...this.points];
      if (tempPoint) {
        points.push(tempPoint);
      }
      points.push(points[0]); // 闭合多边形

      const area = this.calculateArea(points);

      if (this.measureTooltip) {
        this.map.removeLayer(this.measureTooltip);
      }

      const center = this.getPolygonCenter(points);
      this.measureTooltip = L.tooltip({
        permanent: true,
        direction: 'center'
      })
        .setLatLng(center)
        .setContent(this.formatArea(area))
        .addTo(this.map);
    },

    calculateArea(points) {
      // 使用平面几何计算面积
      let area = 0;
      if (points.length > 2) {
        for (let i = 0; i < points.length - 1; i++) {
          const p1 = this.map.project(points[i], this.map.getZoom());
          const p2 = this.map.project(points[i + 1], this.map.getZoom());
          area += (p2.x + p1.x) * (p2.y - p1.y);
        }
        area = Math.abs(area / 2);
        // 根据当前缩放级别计算实际面积
        const scale = this.map.options.crs.scale(this.map.getZoom());
        area = area / (scale * scale);
        // 转换为平方米
        area = area * 40075016.686 * 40075016.686 / (Math.PI * Math.PI);
      }
      return area;
    },

    getPolygonCenter(points) {
      // 计算多边形中心点
      let x = 0, y = 0;
      for (let i = 0; i < points.length; i++) {
        x += points[i].lat;
        y += points[i].lng;
      }
      return L.latLng(x / points.length, y / points.length);
    },

    formatDistance(distance) {
      if (distance > 1000) {
        return (distance / 1000).toFixed(2) + ' 公里';
      }
      return Math.round(distance) + ' 米';
    },

    formatArea(area) {
      // 转换为正数
      area = Math.abs(area);
      if (area > 1000000) {
        return (area / 1000000).toFixed(2) + ' 平方公里';
      }
      return Math.round(area) + ' 平方米';
    },
  }
};
</script>

<style scoped>
.map-container {
  width: 100%;
  height: 100vh;
  position: relative;
}

.map {
  width: 100%;
  height: 100%;
}

.toolbar {
  position: absolute;
  top: 20px;
  left: 50%;
  transform: translateX(-50%);
  background: white;
  padding: 10px;
  border-radius: 4px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
  z-index: 1000;
}

.toolbar button {
  margin: 0 5px;
  padding: 8px 15px;
  border: 1px solid #dcdfe6;
  background: white;
  cursor: pointer;
  border-radius: 4px;
  transition: all 0.3s;
}

.toolbar button:hover {
  color: #409eff;
  border-color: #c6e2ff;
  background-color: #ecf5ff;
}

.toolbar button.active {
  color: #fff;
  background-color: #409eff;
  border-color: #409eff;
}

:deep(.leaflet-tooltip) {
  background: rgba(0, 0, 0, 0.6);
  border: none;
  color: white;
  padding: 5px 10px;
  border-radius: 4px;
  font-size: 12px;
  pointer-events: none;
}

:deep(.area-tooltip) {
  background: rgba(0, 0, 0, 0.8);
  color: white;
  border: none;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.2);
  font-weight: bold;
}

:deep(.leaflet-tooltip::before) {
  border-top-color: rgba(0, 0, 0, 0.6);
}
</style> 